#ifndef HASHACTIVITY_H_JM_20120910
#define HASHACTIVITY_H_JM_20120910
/// @file HashActivity.h 
/// Bazova trieda pre logiku db operacii zalozenych na hashovani - hash aktivity.

// ##
#include "HashBox.h"
#include "../DbOperationVersion.h"
#include "HashActivityHandler.h"

namespace jm4bbx {

	/**
	 * Bazova trieda pre logiku db operacii zalozenych na hashovani - hash 
	 * aktivity. Jedna sa v podstate o druhy krok algoritmu db operacie. V prvom
	 * kroku sa cely jeden operand zahashuje do tabulky a v druhom sa prechdzaju
	 * prvky druheho operandu a pomocou hash tabulky sa vykonava logika db 
	 * operacie.
	 * 
	 * Tato trieda vykova vsetku spolocnu cinnost pre hash aktivity a vyzaduje 
	 * rozhranie pomocou, kt. je mozne implementovat uplne funkcnu hahs aktivitu.
	 **/
	template<class hashBoxType>
	class HashActivity {
		JM_USE_LOGGER(boxes_hash_hashActivity_logger)
	public:
		typedef HashActivityHandler<hashBoxType> HashActivityHanndlerType;
		
		/// Typ triedy, ktora poskytuje tabulku obsahujucu zaheshovanu relaciu.
		typedef typename hashBoxType::HTH HTH;

		///// Typ zaznamov relacie ukladanych do hashovacej tabulky.
		//typedef typename hashBoxType::HashEntry HashEntry;

		///// Typ poloziek hashovacej tabulky zaheshovanej relacie.
		//typedef typename hashBoxType::ExtendedHashEntry ExtendedHashEntry;

		/// Typ politiky zaznamu zaheshovanej relacie.
		typedef typename hashBoxType::policyType policyType;

		/// Type kluca zahesovanej relacie
		//typedef typename hashBoxType::keyType keyType;

		typedef typename hashBoxType::transferValueType transferValueType;

		//typedef typename hashBoxType::valueType valueType;

		HashActivity(const BoxParamPack& p)/*: version_(p)*/ { }
		virtual ~HashActivity() { }

	protected:
		//const DbOperationVersion version_;

		virtual HashActivityHanndlerType* getHashActivityHandler() = 0;
		///**
		//* Spracovanie jedneho zaznamu nezaheshovanej relacie, ktory ma nenulovy 
		//* vyskyt v hashovacej tabulke zaheshovanej relacie.
		//* @param value nezaheshovany zaznam
		//* @param entry zaheshovany zaznam ((kluc, zaznam), nasobnost)
		//**/
		//virtual void handleRecord(transferValueType value, 
		//	typename HTH::ExtendedHashEntry& entry) = 0; 

		///**
		//* Spracovanie jedneho zaznamu nezaheshovanej relacie, ktory ma nulovy 
		//* vyskyt v hashovacej tabulke zaheshovanej relacie.
		//* @param value nezaheshovany zaznam
		//**/
		//virtual void handleNoRecord(transferValueType value) = 0; 

		/**
		* Priznak potreby synchronizacie - nutne vracat true pokial sa bude do 
		* hashovacej tabulky aj zapisovat. 
		**/
		virtual bool synchronize() const = 0;

		/**
		 * Spracovavane data - nezahashovana relacia.
		 **/
		virtual policyType* getData() = 0;

		/**
		 * Priznak, ktory vynuti prerusenie prace {@link #doHashActivity} 
		 * vo vhodnom momente.
		 **/
		virtual bool stopActivity() { return false; }

		/**
		 * Vykonanie hash activity.
		 * @param ig urcenie rozsahu spracovavanych dat a v pripade prerusenia 
		 * {@link @stopActivit} urcenie co este treba spracovat.
		 **/
		void doHashActivity(RootBox::GroupPtr ig) {
			// Pokial je pozadovana synchronizacia tak ju zapnem.

			bool synchronization = synchronize();
			LOG_I("Synchronizacia == " << synchronization);
			HTH::getHashTable()->setSynchronized(synchronization);
			// Priechod datami ktore sa maju spracovat. 
			//size_t noRecordCount = 0, matchRecordCount = 0;			
			LOG_I("Zaznamov pre spracovanie hash aktivitou: " << ig->getReadEnd() - ig->getReadPosition()); 
			for (; ig->getReadPosition() < ig->getReadEnd() && !stopActivity(); 
				ig->moveReadPosition()) {
					auto value = getData()[ig->getReadPosition()];
					if (!HTH::getHashTable()->applyOnExtended(value.getKey(), 
						[&](HTH::ExtendedHashEntry& entry) {
							getHashActivityHandler()->handleRecord(value, entry);
					})) {
						// Nenasiel sa ziaden zodpovedajuci prvok v hashmape
						getHashActivityHandler()->handleNoRecord(value);
					}	
			}
		}
	protected:
		/// Holder spristupnujuci hashovaciu tabulku s datami zaheshovanej relacie.
		//StaticHashTableHolderType tableHolder_;		
	};


} // namespace jm4bbx 

#endif
